import { _decorator, Component, Enum, Material, MeshRenderer, Node, SpriteFrame, SpriteRenderer, tween, v3 } from 'cc';
import { NUMBER, PART, PARTGRADE, PartMaxGrade, PartProperty, PartUpgrade, WeaponData, weaponProperty, WEAPONTYPE } from './GameConstant';
import { GameUtil } from './GameUtil';
import { PrefsManager } from './PrefsManager';
import { ZTool } from '../AshFramework/Utils/ZTool';
import { EventManager, MyEvent } from './EventManager';
import { ResourceUtil } from '../AshFramework/Utils/ResourceUtil';
const { ccclass, property } = _decorator;

@ccclass('Weapon')
export class Weapon extends Component {

    @property({ type: Enum(WEAPONTYPE) })
    WeaponType: WEAPONTYPE = WEAPONTYPE.手枪;

    @property({ type: Node })
    DJs: Node[] = [];

    @property({ type: Node })
    QTs: Node[] = [];

    @property({ type: Node })
    MZJs: Node[] = [];

    @property({ type: Node })
    XYQs: Node[] = [];

    @property(Node)
    PendantNode: Node = null; //挂件

    @property({ type: Node })
    Pendants: Node[] = [];

    @property(MeshRenderer)
    MeshRenderer: MeshRenderer = null;

    @property(Node)
    Muzzle: Node = null;//枪口

    @property(Node)
    Grade: Node = null;

    @property(SpriteRenderer)
    Sprites: SpriteRenderer[] = [];

    @property
    HaveGrade: boolean = false;

    WeaponData: WeaponData = null;

    NormalMaterial: Material = null;//默认材质
    MaxGrade: PARTGRADE = PARTGRADE.GRADE1;//零件最高等级   
    PartUpgrade: PARTGRADE[] = [];//零件升级所需要的等级
    CurPartIndex: number[] = [];//当前零件的下标

    curType: Array<PARTGRADE> = new Array(4);
    nextPart: PART = PART.XYQ;

    protected onLoad(): void {
        // EventManager.ON(MyEvent.SHOWPENDANT, this.showPendant, this);
        if (this.MeshRenderer) this.NormalMaterial = this.MeshRenderer.getMaterial(0);
    }

    protected start(): void {
        this.curType = PrefsManager.Instance.userData.PartGrade[ZTool.GetEnumKeyByValue(WEAPONTYPE, this.WeaponType)];
        this.MaxGrade = PartMaxGrade[ZTool.GetEnumKeyByValue(WEAPONTYPE, this.WeaponType)];
        this.PartUpgrade = PartUpgrade[ZTool.GetEnumKeyByValue(WEAPONTYPE, this.WeaponType)];
        this.CurPartIndex = GameUtil.deepCloneArray(PrefsManager.Instance.userData.PartIndex[ZTool.GetEnumKeyByValue(WEAPONTYPE, this.WeaponType)]);
        this.showPendant();
        this.changeSkin();
        this.showWeapon();
        this.updateData();
        if (this.HaveGrade) this.updateSprite();
    }

    //更新武器数据
    updateData() {
        const weaponName = ZTool.GetEnumKeyByValue(WEAPONTYPE, this.WeaponType);
        const partProperty = PartProperty[weaponName];
        this.WeaponData = JSON.parse(JSON.stringify(weaponProperty[weaponName]));

        for (let index = 0; index < this.curType.length; index++) {
            const grade = this.curType[index];
            this.WeaponData.rate += partProperty[index][0] * grade;
            this.WeaponData.range += partProperty[index][1] * grade;
        }
        this.WeaponData.rate = Number((this.WeaponData.rate).toFixed(2));
        this.WeaponData.range = Number((this.WeaponData.range).toFixed(2));
    }

    upgrade(partType: PARTGRADE) {
        const index: number = this.checkTarget(partType);
        if (index != -1) {
            //升级
            this.curType[index] = partType;
            this.nextPart = index == this.nextPart ? GameUtil.getAdjacentEnumCirculation(PART, this.nextPart, true) : index;
            PrefsManager.Instance.saveData();
            this.showWeapon();
            this.updateData();
            tween(this.node)
                .by(0.2, { scale: v3(0.2, 0.2, 0.2) }, { easing: `quadOut` })
                .by(0.2, { scale: v3(-0.2, -0.2, -0.2) }, { easing: `quadIn` })
                .start();
        }
    }

    showWeapon() {
        //消音器
        if (this.curType[0] >= this.PartUpgrade[2]) {
            this.showPart(this.XYQs, 2);
            this.CurPartIndex[0] = 2;
        } else if (this.curType[0] >= this.PartUpgrade[1]) {
            this.showPart(this.XYQs, 1);
            this.CurPartIndex[0] = 1;
        } else if (this.curType[0] >= this.PartUpgrade[0]) {
            this.showPart(this.XYQs, 0);
            this.CurPartIndex[0] = 0;
        }
        //枪托
        if (this.curType[1] >= this.PartUpgrade[2]) {
            this.showPart(this.QTs, 2);
            this.CurPartIndex[1] = 2;
        } else if (this.curType[1] >= this.PartUpgrade[1]) {
            this.showPart(this.QTs, 1);
            this.CurPartIndex[1] = 1;
        } else if (this.curType[1] >= this.PartUpgrade[0]) {
            this.showPart(this.QTs, 0);
            this.CurPartIndex[1] = 0;
        }
        //弹夹
        if (this.curType[2] >= this.PartUpgrade[2]) {
            this.showPart(this.DJs, 2);
            this.CurPartIndex[2] = 2;
        } else if (this.curType[2] >= this.PartUpgrade[1]) {
            this.showPart(this.DJs, 1);
            this.CurPartIndex[2] = 1;
        } else if (this.curType[2] >= this.PartUpgrade[0]) {
            this.showPart(this.DJs, 0);
            this.CurPartIndex[2] = 0;
        }
        //瞄准镜
        if (this.curType[3] >= this.PartUpgrade[2]) {
            this.showPart(this.MZJs, 2);
            this.CurPartIndex[3] = 2;
        } else if (this.curType[3] >= this.PartUpgrade[1]) {
            this.showPart(this.MZJs, 1);
            this.CurPartIndex[3] = 1;
        } else if (this.curType[3] >= this.PartUpgrade[0]) {
            this.showPart(this.MZJs, 0);
            this.CurPartIndex[3] = 0;
        }

        if (!GameUtil.areArraysEqual(this.CurPartIndex, PrefsManager.Instance.userData.PartIndex[ZTool.GetEnumKeyByValue(WEAPONTYPE, this.WeaponType)])) {
            PrefsManager.Instance.userData.PartIndex[ZTool.GetEnumKeyByValue(WEAPONTYPE, this.WeaponType)] = GameUtil.deepCloneArray(this.CurPartIndex);
            PrefsManager.Instance.saveData();
        }
    }

    showPart(arrNode: Node[], index: number) {
        if (index >= arrNode.length) {
            console.error(`零件没有该部分！`);
            return;
        }
        for (let i = 0; i < arrNode.length; i++) {
            if (i == index) arrNode[i].active = true;
            else arrNode[i].active = false;
        }
    }

    checkUpgrade(partType: PARTGRADE) {
        const index = this.checkTarget(partType);
        if (index == -1) return;
        this.updateSprite(index);
    }


    updateSprite(index: number = -1) {
        for (let i = 0; i < this.curType.length; i++) {
            if (i != index && this.curType[i] == 0) {
                this.Sprites[i].node.active = false;
                continue;
            }
            this.Sprites[i].node.active = true;
            let path = "lv" + this.curType[i];
            const max = PartMaxGrade[ZTool.GetEnumKeyByValue(WEAPONTYPE, this.WeaponType)];
            if (max <= this.curType[i]) {
                path = "最高等级";
            } else if (i == index) {
                path = "升级";
            }
            ResourceUtil.LoadSpriteFrame(path).then((sf: SpriteFrame) => {
                this.Sprites[i].spriteFrame = sf;
            })
        }
    }

    checkTarget(partType: PARTGRADE) {
        const max = PartMaxGrade[ZTool.GetEnumKeyByValue(WEAPONTYPE, this.WeaponType)];
        return GameUtil.findFirstIndexInCircularArray(this.curType, this.nextPart, (e: number) => { return e < partType && e < max });
    }

    changeSkin() {
        if (!this.MeshRenderer) return;
        const number = PrefsManager.Instance.userData.checkedItem.PF;
        let path = "";
        if (NUMBER.NUMBER1 == number) {
            this.MeshRenderer.material = this.NormalMaterial;
            return;
        } else {
            path = "WeaponMaterial" + number;
        }
        ResourceUtil.LoadMaterial(path).then((material: Material) => {
            this.MeshRenderer.material = material;
        })
    }

    showPendant() {
        const index: number = Number(PrefsManager.Instance.userData.checkedItem.GS) - 1;
        if (index >= 0 && index < this.Pendants.length) {
            this.PendantNode.active = true;
            this.showPendantByIndex(index);
        } else {
            this.PendantNode.active = false;
        }
    }

    showPendantByIndex(index: number) {
        for (let i = 0; i < this.Pendants.length; i++) {
            this.Pendants[i].active = false;
        }
        this.Pendants[index].active = true;
    }


}


